package com.leinao.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.leinao.commons.Response;
import com.leinao.config.EnvironmentConfig;
import com.leinao.constant.CalculateEnum;
import com.leinao.constant.Constant;
import com.leinao.constant.ProjectJobHandleEnum;
import com.leinao.job.dao.PaiProjectJobMapper;
import com.leinao.login.dto.LoginResultDto;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
 * 
 * 远程业务调用封装类
 * 
 * 定时逻辑
 * @author wangshoufa 
 * @date 2019年3月19日 下午3:29:45
 *
 */
@Component
public class TaskService {

	private Logger logger = LoggerFactory.getLogger(getClass());

	public static Random random = new Random();

	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private EnvironmentConfig env;

	@Autowired
	private PaiProjectJobMapper paiProjectJobMapper;

    /**
     * @description 异步任务计算耗时
     * @param start 开始时间
     * @param userId 用户id
     * @throws Exception
     */
	@Async("taskExecutor")
	public void doTaskOne(long start, String userId) throws Exception {
		logger.info(" 开始做任务一 to {}", start);
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		logger.info("完成任务一，耗时：" + (end - start) + "毫秒");
	}
	
	
	/**
	 * 
	 * 操作底层运行任务
	 * 
	 * @param userInfo
	 * @param config
	 * @return
	 * @throws HttpServerErrorException
	 * @throws HttpClientErrorException
	 * @author wangshoufa 
	 * @date 2019年2月20日
	 *
	 */
	public Response<String> syncRunningJob(LoginResultDto userInfo, String config) {
		logger.info("syn run a job token: {}, email: {}, config: {}", userInfo.getToken(), userInfo.getEmail(), config);
		JSONObject pobj = JSON.parseObject(config);
		String jobName = pobj.getString("jobName");
		JSONArray tasks = pobj.getJSONArray("taskRoles");
		if(tasks.size() > 0){
			String imagePatch = tasks.getJSONObject(0).getString("image");
			if(StringUtils.isNotBlank(imagePatch)) {
				paiProjectJobMapper.updateImageUseCount(imagePatch);
			}
		}
		logger.debug("will run jobName: {}", jobName);
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
		headers.setContentType(type);
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());
		headers.add("Authorization", "Bearer " + userInfo.getToken());
		List<String> cookies = new ArrayList<>();
		cookies.add("email=" + userInfo.getEmail());
		headers.put(HttpHeaders.COOKIE, cookies);

		HttpEntity<String> formEntity = new HttpEntity<String>(config, headers);
		String body = "";
		//请求调式任务开始时间
		long beginTime = System.currentTimeMillis();
		ResponseEntity<String> responseEntity = restTemplate.exchange(env.getRestServerUrl() + Constant.REST_SERVER_SUBMIT_JOB_API + jobName,
				HttpMethod.PUT, formEntity, String.class);
		long endTime = System.currentTimeMillis();
        DecimalFormat df=new DecimalFormat("0.000");
        String timeConsuming = df.format(((float)(endTime-beginTime))/1000);
        logger.info("请求创建任务接口耗时统计:【耗时="+timeConsuming+"秒】");
		logger.info("request submitJob return: {}", JSON.toJSON(responseEntity));
		if (responseEntity.getStatusCodeValue() == Constant.RESPONSE_STATUS_ACCEPTED) {
			logger.debug("submit job success");
			body = responseEntity.getBody();
			JSONObject jsonObj = JSON.parseObject(body);
			logger.debug("submit job resp: {}", jsonObj);
			if (jsonObj.getString("message").contains("successfully")) {
				return Response.ok(Constant.RESPONSE_STATUS_SUCCESS,ProjectJobHandleEnum.GET_SUCCESS.getSeq(), "运行任务成功", config);
			}
		}
		if (responseEntity.getStatusCodeValue() == Constant.RESPONSE_STATUS_SUCCESS) {
			body = responseEntity.getBody();
			JSONObject jsonObj = JSON.parseObject(body);
			logger.debug("submit job resp: {}", jsonObj);
			if (jsonObj.getInteger("code") == ProjectJobHandleEnum.GET_ERROR.getSeq()) {
				return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ProjectJobHandleEnum.HTTP_SERVER_EXCEPTION.getSeq(), jsonObj.getString("message"), null);
			}
		}
		return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, ProjectJobHandleEnum.GET_ERROR.getSeq(), "运行任务失败", null);
	}
	
	/**
	 * 
	 * 获取剩余算力
	 * @param bitaToken
	 * @return
	 * @author wangshoufa 
	 * @date 2019年3月19日
	 *
	 */
	public Response<Object> syncCheckResource(String bitaToken) {
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
		headers.setContentType(type);
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());
		HttpEntity<String> formEntity = new HttpEntity<String>(headers);
		String body = "";
		try {
			ResponseEntity<String> responseEntity = restTemplate.exchange(env.getUserCalculationPowerUrl() + "?token=" + bitaToken,
					HttpMethod.GET, formEntity, String.class);
			logger.info("request getUserCalculationPower return: {}", JSON.toJSON(responseEntity));
			if (responseEntity.getStatusCodeValue() == Constant.RESPONSE_STATUS_SUCCESS) {
				body = responseEntity.getBody();
				JSONObject jsonObj = JSON.parseObject(body);
				logger.debug("getUserCalculationPower resp: {}", jsonObj);
				if(jsonObj.getInteger("code") == 0) {
					JSONObject jsonObject = jsonObj.getJSONObject("result");
					BigDecimal surplusCalculationPower = jsonObject.getBigDecimal("surplusCalculationPower");
					if(env.getUserCalculationPowerLimit().compareTo(surplusCalculationPower) < 0) {
						return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, CalculateEnum.CALCULATE_ENOUGH.getType(), "当前剩余算力够用!", null);
					}
					else {
						return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, CalculateEnum.CALCULATE_NOT_ENOUGH.getType(), "当前剩余算力不足，请及时充值!", null);
					}
				}
			}
		} catch (Exception e) {
			logger.error(String.format("req getUserCalculationPower error"));
			logger.error(e.getMessage(), e);
			return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, -3, "获取剩余算力失败", null);
		}
		return Response.ok(Constant.RESPONSE_STATUS_SUCCESS, -2, "当前剩余算力不足，请及时充值!", null);
	}
}